package com.archermind.style.service;

import com.archermind.style.bean.*;
import com.archermind.style.pojo.ElementEnum;
import com.archermind.style.pojo.IconTypeEnum;
import com.archermind.style.pojo.RuleText;
import com.feng.fengDUtil.BaseService;
import com.archermind.style.util.ByteUtil;
import com.archermind.style.util.Search;
import com.feng.fengDUtil.Page;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 样式函数
*@Author 丰建立
*@Date 2018/11/7 22:19
*/
@Service
@Transactional
public class DictService  extends BaseService {

    private static final Logger log = LoggerFactory.getLogger(DictService.class);

    public static final BeanCopier bcPoint = BeanCopier.create(RulePoint.class,RuleText.class,false);
    public static final BeanCopier bcLine = BeanCopier.create(RuleLine.class,RuleText.class,false);
    public static final BeanCopier bcRoadSign = BeanCopier.create(RuleRoadSign.class,RuleText.class,false);

    @Autowired
    private StyleTypeService styleTypeService;


    public Page query(Page page, Search search) {
        ArrayList params = new ArrayList();
        String table;
        switch (search.getDictType()){
            case "font":table = "dict_font";break;
            case "fontSize":table = "dict_font_size";break;
            case "dashLine":table = "dict_dash_line";break;
            default:table = "dict_color";
        }
        String sql = "select u.* from "+table+" u where instanceId = ? ";
        params.add(search.getInstanceId());
        if(table.equals("dict_color")){
            sql += " and element = ? ";
            params.add(search.getDictType());
        }
        findPageList(Map.class,sql,page,params.toArray());
        return page;
    }

    /**
     * 查看字典的被引用情况！
     * @return
     */
    public Page dictReference(Page page,Search search){
        Integer instanceId = search.getInstanceId();
        Integer dictId = search.getDictId();
        String dictType = search.getDictType();
        String sql = null;
        ArrayList params = new ArrayList();
        switch (dictType){
            case "point":
                sql="select * from rule_point where instanceId = ? and (fontColor = ? or halocolor = ?)";
                params.add(instanceId);
                params.add(dictId);
                params.add(dictId);
                break;
            case "line":
                sql="select * from rule_line where instanceId = ? and (stroke = ? or strokeSide = ? or fontColor = ? or halocolor = ?)";
                params.add(instanceId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                break;
            case "polygon":
                sql="select * from rule_polygon where instanceId = ? and (fill = ? or borderColor = ?)";
                params.add(instanceId);
                params.add(dictId);
                params.add(dictId);
                break;
            case "building":
                sql="select * from rule_building where instanceId = ? and" +
                        " (roofColor = ? or rootColor = ? or wallColor = ? or windowColor = ? or roofLineColor = ? or wallLineColor = ? or roofLineColor2d = ? or roofColor2d = ? )";
                params.add(instanceId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                params.add(dictId);
                break;
            case "arrow":
                sql="select * from rule_arrow where instanceId = ? and color = ?";
                params.add(instanceId);
                params.add(dictId);
                break;
            case "roadSign":
                sql="select * from rule_roadSign where instanceId = ? and (fontColor = ? or halocolor = ?)";
                params.add(instanceId);
                params.add(dictId);
                params.add(dictId);
                break;
            case "font":
                sql="select * from (select id,instanceId,styleTypeId,scale,fontName from rule_point where instanceId = ? and fontName = ?"
                        +" union select id,instanceId,styleTypeId,scale,fontName from rule_line where instanceId = ? and fontName = ?"
                         +" union select id,instanceId,styleTypeId,scale,fontName from rule_roadsign where instanceId = ? and fontName = ?) x";
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                break;
            case "fontSize":
                sql="select * from (select id,instanceId,styleTypeId,scale,fontSize from rule_point where instanceId = ? and fontSize = ?"
                        +" union select id,instanceId,styleTypeId,scale,fontSize from rule_line where instanceId = ? and fontSize = ?"
                        +" union select id,instanceId,styleTypeId,scale,fontSize from rule_roadsign where instanceId = ? and fontSize = ?) x";
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                break;
            case "dashLine":
                sql="select * from rule_line where instanceId = ? and dashLineName = ?";
                params.add(instanceId);
                params.add(dictId);
                break;
        }
        findPageList(Map.class,sql,page,params.toArray());
        setSubListForPage(page.getData(), StyleType.class,"style","styleTypeId");
        return page;
    }


    /**
     * 获取被使用到的颜色字典
     * @return
     */
    public List<DictColor> usedDictColor(ElementEnum element,Integer[] ruleIds){
        String sql ="select * from dict_color u where exists (select 1 from rule_"+element.name().toLowerCase()+" s where s.id in ("+genePlaceHolders(ruleIds.length)+") and ";
        switch (element){
            case point:
                sql +="(s.fontColor = u.id or s.halocolor = u.id))";
                break;
            case line:
                sql +="(s.stroke = u.id  or s.strokeSide = u.id  or s.fontColor = u.id  or s.halocolor = u.id ))";
                break;
            case polygon:
                sql +="(s.fill = u.id  or s.borderColor = u.id ))";
                break;
            case building:
                sql +="(s.roofColor = u.id  or s.rootColor = u.id  or s.wallColor = u.id  or s.windowColor = u.id  or s.roofLineColor = u.id  or s.wallLineColor = u.id  or s.roofLineColor2d = u.id  or s.roofColor2d = u.id  ))";
                break;
            case arrow:
                sql +=" s.color = u.id  )";
                break;
            case roadSign:
                sql +="(s.fontColor = u.id or s.halocolor = u.id))";
                break;
          /*  case "font":
                sql="select * from (select id,instanceId,styleTypeId,scale,fontName from rule_point where instanceId = ? and fontName = ?"
                        +" union select id,instanceId,styleTypeId,scale,fontName from rule_line where instanceId = ? and fontName = ?"
                        +" union select id,instanceId,styleTypeId,scale,fontName from rule_roadsign where instanceId = ? and fontName = ?) x";
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                params.add(instanceId);
                params.add(dictId);
                break;
            case "dashLine":
                sql="select * from rule_line where instanceId = ? and dashLineName = ?";
                params.add(instanceId);
                params.add(dictId);
                break;*/
        }
        return sql(sql).list(DictColor.class,ruleIds);
    }

    public List<DictDashLine> usedDashLine(ElementEnum element,Integer[] ruleIds){
        if(!element.equals(ElementEnum.line)){
            return Collections.emptyList();
        }
        String sql ="select * from dict_dash_line u where exists (select 1 from rule_line s where s.id in ("+genePlaceHolders(ruleIds.length)+") and s.dashLineName = u.id)";
        return sql(sql).list(DictDashLine.class,ruleIds);
    }

    public List<DictFont> usedFont(ElementEnum element,Integer[] ruleIds){
        String sql ="select * from dict_font u where exists (select 1 from rule_"+element.name().toLowerCase()+" s where s.id in ("+genePlaceHolders(ruleIds.length)+") and s.fontName = u.id)";
        return sql(sql).list(DictFont.class,ruleIds);
    }

    public List<DictFontSize> usedFontSize(ElementEnum element, Integer[] ruleIds) {
        String sql ="select * from dict_font_size u where exists (select 1 from rule_"+element.name().toLowerCase()+" s where s.id in ("+genePlaceHolders(ruleIds.length)+") and s.fontSize = u.id)";
        return sql(sql).list(DictFontSize.class,ruleIds);
    }

    public void delDict(String ids,String table) {
        String[] idArray = ids.split(",");
        sql("delete from "+table+" where id in ("+genePlaceHolders(idArray.length)+")").update(idArray);
    }

    //导入样式时专用
    public static ThreadLocal<Map<String,DictColor>> colorMap = new ThreadLocal<Map<String,DictColor>>();
    //导入样式 图片路径
    public static ThreadLocal<Map<String,String>> iconMap = new ThreadLocal<Map<String,String>>();
    public Integer getColorId(ElementEnum element, Integer instanceId, String rgbw) {
        if(StringUtils.isEmpty(rgbw)){
            return null;
        }
        String colorStr ;
        if(rgbw.length()==7 ){
            colorStr = rgbw.toLowerCase()+ "ff";
        }else if(rgbw.length()==9){
            colorStr = rgbw.toLowerCase();
        }else{
            return null;
        }
        String key = new StringBuilder(colorStr).append("#").append(element.name()).toString();
        DictColor colorDict = colorMap.get().get(key);
        if(colorDict == null){
            colorDict = new DictColor(instanceId,element,colorStr,colorStr.substring(0,7),colorStr.substring(7,9));
            super.insert(colorDict);
            colorMap.get().put(key,colorDict);
        }
        return colorDict.getId();
    }

    public Integer getFontId(Integer instanceId, String fontName) {
        if(StringUtils.isEmpty(fontName)){
            return null;
        }
        DictFont font = this.sql("select * from dict_font where instanceId = ? and val = ?").one(DictFont.class,instanceId,fontName);
        if(font== null){
            font = new DictFont(instanceId,fontName,fontName);
            super.insert(font);
        }
        return font.getId();
    }

    public Integer getFontSizeId(Integer instanceId, String fontSize) {
        if(fontSize == null){
            return null;
        }
        DictFontSize size = this.sql("select * from dict_font_size where instanceId = ? and val = ?").one(DictFontSize.class,instanceId,fontSize);
        if(size== null){
            size = new DictFontSize(instanceId,fontSize+"",Integer.valueOf(fontSize));
            super.insert(size);
        }
        return size.getId();
    }

    public Integer getDashLineId(Integer instanceId, String dashLineName) {
        if(StringUtils.isEmpty(dashLineName)){
            return null;
        }
        DictDashLine font = this.sql("select * from dict_dash_line where instanceId = ? and name = ?").one(DictDashLine.class,instanceId,dashLineName);
        if(font!= null){
            return font.getId();
        }
        return null;
    }

    public void processXMLDom(Element element, Integer instanceId) {
        Element dashLineStyleDefine = element.element("DashLineStyleDefine");
        List<Element> list = dashLineStyleDefine.elements("DashLineItem");
        for(Element one : list) {
            DictDashLine dashLine = new DictDashLine();
            dashLine.setInstanceId(instanceId);
            dashLine.setName(one.attributeValue("dash-line-name"));
            dashLine.setBegin(ByteUtil.parseByte(one.attributeValue("from")));
            dashLine.setEnd(ByteUtil.parseByte(one.attributeValue("to")));
            dashLine.setSideDashlineArray(one.attributeValue("side-dashline-array"));
            dashLine.setStrokeDashlineArray(one.attributeValue("stroke-dashline-array"));
            dashLine.setxRoate(ByteUtil.parseInteger(one.attributeValue("x-roate")));
            dashLine.setxAntialising(one.attributeValue("x-antialising"));
            super.insert(dashLine);
        }

        //List<IconType> iconTypeList = selectAll(IconType.class);

        Element iconStyleDefine = element.element("IconStyleDefine");
        List<Element> iconItemList = iconStyleDefine.elements("IconItem");
        for(Element iconItem : iconItemList) {
             Element iconLayer = iconItem.element("IconLayer");

            String iconFilename = iconItem.attributeValue("icon-filename");
            if(StringUtils.isNotEmpty(iconFilename) && iconFilename.indexOf("/")>-1){
                String[] strs = iconFilename.split("/");
                if(strs.length==2){
                    String folder = strs[0];
                    String name = strs[1].replaceAll("@\\dx.",".");
                    String aliasName = iconItem.attributeValue("icon-name");
                    iconMap.get().put(aliasName,name);
                    String scaleId = iconLayer.attributeValue("scaleid");

                    IconTypeEnum iconType =  IconTypeEnum.valueOf(iconItem.attributeValue("icon-type"));
                    if(iconType!=null){
                        IconDistri iconDistri = new IconDistri(name,iconType.getValue(),ByteUtil.parseInteger(scaleId));
                        saveOrUpdate(iconDistri);
                    }
                    StyleType iconStyleType = styleTypeService.styleMap.get().get("icon#"+aliasName);
                    InstanceIcon sprite = new InstanceIcon(name,instanceId,aliasName,iconStyleType.getCode());
                    super.insert(sprite);
                    //添加新的图片文件夹
                    //createFolder(folder,iconTypeList);
                }else {
                    System.out.println(iconFilename);
                }
            }
        }
    }

    private void createFolder(String folder, List<IconType> iconTypeList) {
        for(IconType iconType:iconTypeList){
            if(folder.equals(iconType.getText())){
                return;
            }
        }
        IconType item = new IconType();
        item.setText(folder);
        insert(item);
        iconTypeList.add(item);
    }

    public String getIconPath(String iconName) {
        if(StringUtils.isNotEmpty(iconName)){
           return iconMap.get().get(iconName);
        }
        return null;
    }

    List<DictDashLine> getDictDashLines(Integer instanceId) {
        return sql("select * from dict_dash_line where instanceId = ?").list(DictDashLine.class, instanceId);
    }

    public DictDashLine getDictDashLine(Integer dashLineName, List<DictDashLine> dashLines) {
        if(dashLineName != null){
            for(DictDashLine color:dashLines){
                if(color.getId().equals(dashLineName)){
                    return color;
                }
            }
        }
        return null;
    }

    public Integer getDictDashLineId(DictDashLine dashLine) {
        if(dashLine != null){
            return dashLine.getId();
        }
        return null;
    }

    public DictColor getDictColor(Integer fontColor, List<DictColor> colors) {
        if(fontColor != null){
            for(DictColor color:colors){
                if(color.getId().equals(fontColor)){
                    return color;
                }
            }
        }
        return null;
    }

    public Integer getDictColorId(DictColor color) {
        if(color != null){
            return color.getId();
        }
        return null;
    }

    public DictFont getDictFont(Integer fontName, List<DictFont> fonts) {
        if(fontName != null){
            for(DictFont font:fonts){
                if(font.getId().equals(fontName)){
                    return font;
                }
            }
        }
        return null;
    }

    public Integer getDictFontId(DictFont font) {
        if(font != null){
            return font.getId();
        }
        return null;
    }
    public DictFontSize getDictFontSize(Integer fontSize, List<DictFontSize> fontSizes) {
        if(fontSize != null){
            for(DictFontSize item:fontSizes){
                if(item.getId().equals(fontSize)){
                    return item;
                }
            }
        }
        return null;
    }


    public Integer getDictFontSizeId(DictFontSize dictFontSize) {
        if(dictFontSize != null){
            return dictFontSize.getId();
        }
        return null;
    }

    //color 都不属于instanceId ,需要复制到instance中，先查重复定义的
    public void mergeColor(List<DictColor> colors, ElementEnum element, Integer instanceId) {
        BeanCopier bc = BeanCopier.create(DictColor.class,DictColor.class,false);
        String sql = "select * from dict_color c where c.instanceId = ? and c.element = ? and c.color = ? and c.transparent = ?";
        for(DictColor toColor:colors){
           DictColor fromColor = sql(sql).one(DictColor.class,instanceId,element.name(),toColor.getColor(),toColor.getTransparent());
           if(fromColor!=null){
               bc.copy(fromColor,toColor,null);
           }else {
               toColor.setId(null);
               toColor.setInstanceId(instanceId);
           }
        }
    }

    public void mergeFont(List<DictFont> fonts, Integer instanceId) {
        BeanCopier bc = BeanCopier.create(DictFont.class,DictFont.class,false);
        String sql = "select * from dict_font c where c.instanceId = ? and c.val = ? ";
        for(DictFont toFont:fonts){
            DictFont fromFont = sql(sql).one(DictFont.class,instanceId,toFont.getVal());
            if(fromFont!=null){
                bc.copy(fromFont,toFont,null);
            }else {
                toFont.setId(null);
                toFont.setInstanceId(instanceId);
            }
        }
    }

    public void mergeFontSize(List<DictFontSize> fontSizes, Integer instanceId) {
        BeanCopier bc = BeanCopier.create(DictFontSize.class,DictFontSize.class,false);
        String sql = "select * from dict_font_size c where c.instanceId = ? and c.val = ? ";
        for(DictFontSize to:fontSizes){
            DictFontSize from = sql(sql).one(DictFontSize.class,instanceId,to.getVal());
            if(from!=null){
                bc.copy(from,to,null);
            }else {
                to.setId(null);
                to.setInstanceId(instanceId);
            }
        }
    }

    public void mergeDashLine(List<DictDashLine> dashLines, Integer instanceId) {
        BeanCopier bc = BeanCopier.create(DictDashLine.class,DictDashLine.class,false);
        String sql = "select * from dict_dash_line c where c.instanceId = ? " +
                "and c.sideDashlineArray = ?  and c.strokeDashlineArray = ?  and c.xRoate = ?  and c.xAntialising = ? ";
        for(DictDashLine toDashLine:dashLines){
            DictDashLine fromDashLine = sql(sql).one(DictDashLine.class,instanceId,toDashLine.getSideDashlineArray(),toDashLine.getStrokeDashlineArray(),toDashLine.getxRoate(),toDashLine.getxAntialising());
            if(fromDashLine!=null){
                bc.copy(fromDashLine,toDashLine,null);
            }else {
                toDashLine.setId(null);
                toDashLine.setInstanceId(instanceId);
            }
        }
    }



}
